﻿namespace BlogsAPI.Search
{
    using System.IO;
    using Abstract;
    using System.Net;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Diagnostics;
    using System;
    using System.Web;

    /// <summary>
    /// Класс для работы с поиском по НОВОСТЯМ от яндекса
    /// </summary>
    public class NewsYandex : BasicSearch
    {
        /// <summary>
        /// Конструктор
        /// </summary>
        public NewsYandex()
        {
            separator_and = "&&";
            separator_or = "||";
            separator_not = "-";
        }

        private static readonly Regex parser = new Regex(@"<a[^>]+?class=\Wb-link\W[^>]+?href=\W(http[^""]+)""[^>]+>(.*?)</a",
            Regexoptions);

        /// <summary>
        /// Формируем ссылку для поиска в яндексе числа отзывов и комментов
        /// </summary>
        /// <param name="text">текст для поиска</param>
        /// <param name="from">дата времени от</param>
        /// <returns>Ссылка для поиска в Яндексе</returns>
        private static String FormYandexNewsSearch(String text, DateTime? from = null)
        {
            return String.Format(
 //"http://news.yandex.ru/yandsearch?rpt=nnews2&within=8&grhow=clutop&date=within&text={0}&within=777&from_day={1}&from_month={2}&from_year={3}&to_day=&to_month=&to_year=&numdoc=100&Done=%D0%9D%D0%B0%D0%B9%D1%82%D0%B8",
 "http://news.yandex.ru/yandsearch?rel=tm&grhow=clutop&to_day=&from_year={3}&from_month={2}&ncrnd=7796&numdoc=100&within=8&within=777&text={0}&to_year=&from_day={1}&to_month=&rpt=nnews2",               
                HttpUtility.UrlEncode(text).Replace("&", "%26"),
                from == null ? "" : from.Value.ToString("dd"),
                from == null ? "" : from.Value.ToString("MM"),
                from == null ? "" : from.Value.ToString("yyyy"));
        }

        /// <summary>
        /// Формирование разобранного поста из того что дает яндекс.
        /// </summary>
        /// <param name="yad"></param>
        /// <returns></returns>
        private BlogPost ParseBlogPost(Match yad)
        {
            return new BlogPost
            {
                Link = new Uri(yad.Groups[1].Value),
                Body = yad.Groups[2].Value.Replace("strong","b"),//заменяем <strong> на <b> для общего стандарта!
                Subject = yad.Groups[2].Value.Replace("strong", "b"),//заменяем <strong> на <b> для общего стандарта!
                Existance = true,
                Published = DateTime.Now
            };
        }

        /// <summary>
        /// Получение сслки для цитирования по посту
        /// </summary>
        /// <param name="text">текст для поиска</param>
        /// <param name="fromDate">дата начиная с которой искать объекты, может быть нулом, тогде по максимуму!</param>
        /// <returns>массив постов удовлетворяющих поиску</returns>
        public override BlogPost[] SearchFor(String text, DateTime? fromDate)
        {
            BlogPost[] oRes = new BlogPost[0];
            try
            {
                HttpWebRequest myHttpWebRequest = MakeRequest(FormYandexNewsSearch(text, fromDate));
                myHttpWebRequest.AllowAutoRedirect = false;
                myHttpWebRequest.Referer = "http://"+myHttpWebRequest.RequestUri.Host;
                myHttpWebRequest.Method = "GET";
                HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
                string reply = (new StreamReader(myHttpWebResponse.GetResponseStream(), Encoding.UTF8)).ReadToEnd();
                myHttpWebResponse.Close();
                MatchCollection mc = parser.Matches(reply);
                if(mc.Count>0)
                {
                    foreach (Match match in mc)
                    {
                        if(match.Groups[1].Value.Contains("yandex.ru")) continue;
                        BlogPost bp = ParseBlogPost(match);
                        if(bp != null)
                        {
                            Array.Resize(ref oRes, oRes.Length + 1);
                            oRes[oRes.Length - 1] = bp;
                        }
                    }
                }
            }catch(Exception e1)
            {
                Debug.WriteLine("SearchFor failed cause " + e1.Message);
            }
            return oRes;
        }
    }
}
